﻿
package extremefx.remoting {
	import extremefx.crypto.Random;
	import extremefx.crypto.hash.SHA1;
	import extremefx.tools.Base64;
	import extremefx.tools.StringUtils;

	import flash.utils.ByteArray;

	/**
	 * @author Marcelo Volmaro
	 */
	public class WsseAuthorization implements IAuthorization {
		private static var _sha1:SHA1 = new SHA1();
		private var _pass:String;
		private var _user:String;

		public function WsseAuthorization(pUsername:String, pPassword:String) {
			_user = pUsername;
			_pass = pPassword;
		}
		
		public function authorize(pRequest:RestRequest):void {
			var created:String = _isoDateTime();
			var ba:ByteArray = new ByteArray();
			ba.writeUTFBytes(created + Random.text(32));
			
			var nonce:String = Base64.encode(_sha1.hash(ba));
			ba.clear();
			ba.writeUTFBytes(nonce + created + _pass);
			
			pRequest.addHeader("Authorization", "WSSE profile=\"UsernameToken\"");
			pRequest.addHeader("X-WSSE","UsernameToken Username=\"" + _user + "\", PasswordDigest=\"" + Base64.encode(_sha1.hash(ba)) + "\", Created=\"" + created + "\", Nonce=\"" + nonce + "\"");
		}
		
		private function _isoDateTime():String {
			var today:Date = new Date();
			var year:Number = today.getFullYear();
			var hour:Number = today.getHours();
			var hourUTC:Number = today.getUTCHours();
			var diff:Number = hour - hourUTC;
			var hourdifference:Number = Math.abs(diff);
			var minute:Number = today.getMinutes();
			var minuteUTC:Number = today.getUTCMinutes();
		    
			if (minute != minuteUTC && minuteUTC < 30 && diff < 0) { hourdifference--; }
			if (minute != minuteUTC && minuteUTC > 30 && diff > 0) { hourdifference--; }
		    
			var minutedifference:String = (minute == minuteUTC) ? ":00" : ":30";
	
		    return (
		    	year + "-" +
		    	StringUtils.padLeft((today.getMonth() + 1).toString(), 2, "0") + "-" +
		    	StringUtils.padLeft((today.getDate()).toString(), 2, "0") + "T" +
		    	StringUtils.padLeft(hour.toString(), 2, "0") + ":" +
		    	StringUtils.padLeft(minute.toString(), 2, "0") + ":" +
		    	StringUtils.padLeft(today.getSeconds().toString(), 2, "0") +
		    	((diff < 0) ? "-" : "+") + 
				StringUtils.padLeft((hourdifference + minutedifference), 2, "0") 
		    );
		}
	}
}
